
Original is Qrome marquee scroller v3.0.3
	https://github.com/Qrome/marquee-scroller, last update Apr 30, 2024
Forked to rob040 LED matrix Clock
	https://github.com/rob040/LEDmatrixClock

TODO items
1. PRIO 1: get rid of TimeZoneDB registration requirement
   This req is not needed, as the Weather API supplies current timezone in seconds from UTC, and performs automatic DST changes, which makes conversion from country/city to TZ string and TZ string interpretation not needed.
   => DONE v3.1.4
2. Update OpenWeather API; new API key requests can no longer use the "GET /data/2.5/group?" request, but must use the current "GET /data/2.5/weather?" request. The returned json string is different and requires adaptation.
   => DONE v3.1.5 (OWM API) + v3.1.6 (OWM Client rework)
3. Reduce RAM usage; most static text and html is duplicated in RAM, most can be prevented
   There is only 80kB RAM in ESP8266
   => DONE v3.1.8  saves 6352 bytes RAM and 2728 bytes FLASH.
      There were some functional improvements as well
4. Add basic MQTT support (there is already PR#265 for this, which looks good as a start)
   => DONE v3.1.11
4.1 Add MQTT server username and password authentication and configuration
   => DONE v3.1.23
4.2 Add MQTT control of display brightness, display on/off,
4.3 publish some weather info,
4.4 pub statistical data,
4.5 pub debug help, like free heap, max allocatable block; to monitor memory fragmentation and memory leaks
5. Compile under PlatformIO / PIOarduino in VScode, perhaps saying goodbye to Arduino IDE (PIO provides control over used library versions, which is near impossible with Arduino IDE for different projects)
   => Done, Arduino IDE still supported
6. OpenWeatherMap only accepts 1 CityID and produces 1 current weather report: remove presumed flexibility here.
   => DONE
7. Fix naming like read/write 'CityIDs', 'handleLocations' 'GET /location', which are misnomers for __configuration__ update, save, restore
   => DONE v3.1.8
7.1 opening "http://<deviceIP>/location" will erase your configured configuration! Prevent this!
   -> now called /saveconfig
   -> todo in all /save* requests
   => DONE v3.1.9
8. Fix some idiosyncrasies, coding mis-style (uppercase variables, space between function name and its arguments, ...), TODO's
   => ongoing
9. Prioritize metric and SI-units as config defaults and select archaic colonial/imperial units as an option, same goes for 24h/12h clock. Get rid of 'military time'.
10. Go through list of issues and PRs of original repo and check which are 'solved' by this Fork
    may be provide PR's to Original repo, though the changes might be too large to be acceptable/merge-able
    => ongoing
11. make it compile and run on ESP32 variants
    => future (though it shouldnt be that hard, been there done that...) For me this is 'easy' reuse of some older HW, hence stick with ESP8266.
12. Adaptive brightness option; add LDR on ADC input and heavily filter for slow changes
13. make it possible to show alternate display (temperature) statically (without scrolling), alternating with time, like 5s temperature, 55s time
    => DONE v1.3.19 (disable all display options will leave temperature, which is statically shown for 5s)
13.1 make display functions showing time, scrolling message, static temperature display re-entrant from loop,
    e.g. call scroll message for every pixel shift, call show time for every 1/2 second to blink center colon when enabled, etc
    This allows the webserver and OTA to be serviced within the loop, iso at 3-4 places, and should increase web service responsiveness.
    ==> done v3.1.36
14. Change from OWM city-ID to city/[state/]country or lat/lon coordinates or allow them all for maximum flexibility.
    The OWM geocoding-api will translate to lat/lon coordinates for weather requests. ==> not required; std API 2.5 does support them.
    ==> DONE v3.1.40
15. Check which font type/file is used.
    -> build-in to Adafruit_GFX_library glcdfont.c, fixed
16. Add slider checkbox (see w3schools) (instead of oldfashioned checkboxes) to mainpage header for autorefresh and darkmode
    ==> DONE v3.1.24 #9364fb50 20250701: Adds autorefresh and darkmode.
17. Enhance display off quiet period with options like {display off, dimmed, dimmed and no motion}.
    ==> DONE v3.1.44
18. Add local temperature sensor and show inside temperature. Support only a few I2C sensors. Caveat: here we might get requests like can you support this or that sensor....
19. Add Config option: "Flash System LED on WiFi activity"; the blue onboard LED is quite bright, shining through the case and can be annoying.
      ==> DONE v3.1.31
20. config page rework; In general, create more logical order, it is a mess now.
20.1  group 'Display' items name 'LED display',
      ==> Done v3.1.25 All config page items are now re-grouped
20.2  move 'use metric' to bottom (point 9!),
      -> relocated to Data Display Settings group
20.3  rename 'Minutes Between Refresh Data' to 'Clock Sync / Weather Refresh (minutes)'
      and change NTP sync accordingly,
      => NTP sync fixed in v3.1.22
      ==> DONE  v3.1.25; now called 'Data refresh interval'
20.4  move 'Minutes Between Scrolling Data' to display items and rename to 'Display interval',
      ==> DONE  v3.1.25; now called 'Display Scrolling Data interval'
20.5  rename 'Flash : in the time' to 'Blink time colon',
      ==> Done v3.1.25
20.6  move 'marquee message' setting to 3rd line and name 'Scroll message',
      ==> Done v3.1.25
20.7  'Start time'/'End time' group in 'Quiet period' with start and end reversed + point 17,
      - later
20.8  Add config of display width (# of tiles, default 4, max 32?); rename numberOfHorizontalDisplays, add to R/W configuration,
      ==> Done v3.1.25
20.9  Add wide clock style config, different screen formats for 8+ tiles: HH:MM, HH:MM:SS, HH:MM *CF, HH:MM %RH, mm dd HH:MM,  HH:MM Www DD (12 chars! 8 tiles fit 10 chars! ,
      (There are smaller fonts, but everything in this code is assuming fixed size chars.)
      ==> Done v3.1.25; now there are 8 variants. No font change.
21. News headlines: Do not use newsapi.org, it is NOT free but costs 450 USD per __MONTH__ (5400 USD per annum)! ridiculous pricing for this Indian company!
    ==> Done v3.1.26
22. Change to use latest Arduino json V7 library. this makes the JsonStreamingParser and json buffer size (mis)calculation unnecessary.
    ==> Done v3.1.27  (thanks to bit4man)
23. Update to new PiHole by bit4man
    -> will not do that; Pi-hole doesn't bring enough for this scrolling message display.
24. Fix potential wait forever loop in OWMClient; add timeout of 2s to wait for data from OWM server after connect.
    ==> Done in v3.1.28
25. Make Display Temperature also configurable, to allow for time only display. (weather APIkey is still needed for automatic DST timezone).
    ==> Done in v3.1.29
26. Add a "Do not scroll weather data display" option to display weather data fitting on one screen to NOT scroll but shown sequentially.
    Multiple Display options can be ticked, only weather items that fit on the display are displayed sequentially for 5s each.
    This is the option for motion sensible persons. This changes point 13.
    ==> Done in v3.1.30
    Extend this also to MQTT message fitting on display; larger messages will be scrolled.
27. Scrolling messages are clocked with fluctuating timings (clock jitter), causing irregular and inconsistent spacing and distortion of the text.
    -> partially done in v3.1.36
    Using a HW timer interrupt to shift SPI data to display will improve this considerably. Is there a SPI data DMA possibility?
28. The marquee message and MQTT message could contain characters that must be converted to %HEX before included in html
    ==> DONE in v3.1.39, however, only for ASCII chars. HTML could send UTF8 characters, such as € EURO symbol.
    There is no conversion from UTF8 to ANSI (Extended ASCII or CP437) available
29. Restructure the main loop: have an executive like structure, with all process functions return in limited time.
    ==> DONE in v3.1.36
30. The message string from HTML page is in UTF8 encoding, because the HTML page is. This means the user can specify characters outside ASCII-96 range.
    The Adafruit GFX uses the CP437 code-page for LED Matrix display, and none of the optional free type fonts are useable here (none are constant width and fit in 5x7 matrix).
    Convert a limited UTF8 subset of special characters to the existing CP437 characters. 
    Note for the Euro sign '€' we need a modified CP437; some suggest char code 0x80 as in ANSI charset (Windows-1252).
    Otoh., who needs the extended charset (beyond ASCII-96) and is satisfied with the limitations of CP437?
      https://upload.wikimedia.org/wikipedia/commons/f/f8/Codepage-437.png
      https://nagatan.web.fc2.com/moji/codepage437.png
      https://cdn-learn.adafruit.com/assets/assets/000/103/682/original/graphic_lcds_gfx-cp437-bug.png
      https://en.wikipedia.org/wiki/UTF-8

Future
- Add REST API for various controls
- Update webpage with json data; requires JS code (ie do html update client side iso. server side)
- Investigate if we can run without adafruit library
	https://github.com/markruys/arduino-Max72xxPanel/pull/7  BitBang and no Adafruit_GFX #7
	who defines the character map?
Major overhaul
+ html main page: store whole page as one big array and process it as a stream, search for $marker$. Have a table with markers matching a callable function that returns the replacement text. callback could be anon inline function. This should reduce the number of string operations and memory allocations considerably.
Alternatively, read base html from FS file, then size is even less important. What is file read performance? serve own css as file?
+

ESP_WiFiManager_Lite issues
- NUM_WIFI_CREDENTIALS is fixed to 2 in ESP_WiFiManager_Lite.h,
  however the remaining code appears to be suited for a flexible number.
  What is the decision behind the fixed number?
  => the webpage markup isn't suited for != 2
  ==> done this myself, since the library is now unmaintained it is now included as lib.
- When either using DOUBLERESETDETECTOR (DRD) or MULTIRESETDETECTOR (MRD) there is for ESP8266 no possibility to
  configure to use RTC memory to store reset state, although the config options suggest this posibility.
  What is the reason behind this?
  --> The RTC memory variant appears to be un-implemented
  ==> select EEPROM to be used for wifi settings and DRD; these won't be erased by FS upload.
- Always output warning:
 .pio\libdeps\default\ESP_WiFiManager_Lite\src/ESP_WiFiManager_Lite.h:95:6: warning: #warning Using EEPROM in ESP_WiFiManager_Lite.h [-Wcpp]
   95 |     #warning Using EEPROM in ESP_WiFiManager_Lite.h
 ==> disabled; warning serves no purpose; there is nothing wrong
- The ESP_WiFiManager_Lite has way too many configuration parameters, of which some are unexpliccably fixed in the library.
  Storing the (MRD/DRD) reset detector flags in the filesystem adn writing them while expecting resets is not a good idea.
  They should be stored in some memory that is not cleared upon reset (__NOINIT_ATTR on ESP32, RTC memory on ESP8266).
- Why two different solutions doing basically the same: DOUBLERESETDETECTOR (DRD) or MULTIRESETDETECTOR (MRD) ? get rid of one
- In both DRD and MRD implementation, the main flag (uint32_t) is double defined, both in uppercase and lowercase.
  The significance of that is beond me, it appears to serve no purpose; probably has to do with some external modification history...
--> All Done v3.2.0 
  TODO: Fork that library and ref to that one iso including it.


